package com.example.demo.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.common.Result;
import com.example.demo.entity.Files;
import com.example.demo.service.impl.FileServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * 文件上传相关接口
 */
@RestController
@RequestMapping("/file")
public class FileController {
    @Value("${files.upload.path}")
    private String fileUploadPath;
    @Resource
    private FileServiceImpl fileService;
    /**
     * 文件上传
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public Result upload(@RequestParam MultipartFile file) throws IOException {
       String originalFilename =  file.getOriginalFilename();
       String type =  FileUtil.extName(originalFilename);
       long size = file.getSize();

       String uuid =  IdUtil.fastSimpleUUID();
       String fileUuid = uuid + StrUtil.DOT + type;
       File uploadFile = new File(fileUploadPath +fileUuid);
       File parentPath = uploadFile.getParentFile();
        if(!parentPath.exists()){
            parentPath.mkdirs();
        }

       String url;
       String md5;
        file.transferTo(uploadFile);
        md5 = SecureUtil.md5(uploadFile);
        Files dbFiles = getFileMd5(md5);

       // 当文件存在获取文件的md5
           // 获取文件的md5 通过对比md5 避免重复上传内容相同的文件
           // 从数据库查询是否存在相同的记录
        if(dbFiles != null){
            url = dbFiles.getUrl();
            // 文件存在,删除刚才上传的文件
            uploadFile.delete();
        }else {
            url =  fileUuid;
        }
        Files saveFile = new Files();
        // 获取文件的url
        saveFile.setName(originalFilename);
        saveFile.setType(type);
        saveFile.setSize(size / 1024);
        saveFile.setUrl(url);
        saveFile.setMd5(md5);
        fileService.getBaseMapper().insert(saveFile);
       // 先存储到磁盘
        return Result.success(url);
    }
    // 删除
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id){
        Files files = fileService.getBaseMapper().selectById(id);
        files.setIsDelete(true);
        return Result.success(fileService.updateById(files));
    }
    // 批量更新
    @PostMapping("/file/batch")
    public Result deleteBatch(List<Integer> ids){
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id",ids);
        List<Files> files = fileService.getBaseMapper().selectList(queryWrapper);
        for (Files file : files){
            file.setIsDelete(true);
            fileService.updateById(file);
        }
        return Result.success();
    }
    @GetMapping("/{fileUuid}")
    public void downloadFile(@PathVariable String fileUuid, HttpServletResponse httpServletResponse) throws IOException {
        File uploadFile = new File(fileUploadPath + fileUuid);
        ServletOutputStream os = httpServletResponse.getOutputStream();
        httpServletResponse.setContentType("application/vnd.ms-excel;charset=utf-8;");
        httpServletResponse.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileUuid,"UTF-8"));
        httpServletResponse.setHeader("Access-Control-Allow-Origin","*");
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();
    }

    private  Files getFileMd5(String md5){
        // 查询文件的md5 是否存在
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5",md5);
        List<Files> fileList = fileService.getBaseMapper().selectList(queryWrapper);
        return fileList.size() == 0  ? null : fileList.get(0);
    }

    @GetMapping("/list")
    public Result findPage(@RequestParam Integer pageNum, @RequestParam Integer pageSize){
        IPage<Files> page = new Page<>(pageNum,pageSize);
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete",false);
        return Result.success(fileService.page(page,queryWrapper));
    }
}
